項目29 有効な状態のみ表現する型を作る
効果的な型設計の鍵は、有効な状態しか表せない型を作ること
ページ選択に伴いコンテンツがロードされ、表示するアプリケーションの状態を表す型を考える
良くない例
code:ts
interface State {pageText: string; isLoading: boolean; error?: string;}
問題点
状態を表現するためのパターンが多すぎる(様々な組み合わせを考慮する必要がある)
isLoadingとerrorの両方をセット可能だが、そのような状態は不正
型設計が悪いと、コードが複雑になる
code:ts
function renderPage(state: State) {
if (state.error) {
return Error! Unable to load ${currentPage}: ${state.error};
} else if (state.isLoading) {
return Loading ${currentPage}...;
}
return <h1>${currentPage}</h1>\n${state.pageText};
}
良い例
code:ts
interface RequestPending {state: 'pending';}
interface RequestError {state: 'error'; error: string;}
interface RequestSuccess {state: 'ok'; pageText: string;}
type RequestState = RequestPending | RequestError | RequestSuccess;
interface State {currentPage: string; requests: {page: string: RequestState};}
良い点
タグ付きユニオンを使用して、ネットワークリクエストが取りうる複数の状態をそれぞれ明示的にモデリングしている
不正な状態が生まれない
型設計が良いのでコードがシンプル
code:ts
function renderPage(state: State) {
const {currentPage} = state;
const requestState = state.requestscurrentPage;
switch (requestState.state) {
case 'pending':
return Loading ${currentPage}...;
case 'error':
return Error! Unable to load ${currentPage}: ${requestState.error};
case 'ok':
return <h1>${currentPage}</h1>\n${requestState.pageText};
}
}
#TypeScript